﻿using System;
using System.Net;
using System.Linq;
using System.Xml.Linq;
using System.IO;

namespace SeoulOpenApi
{
    public class REST_BaseService
    {
        #region Public

        /// <summary>
        /// 서울시 API접속 ID
        /// </summary>
        public string UserID { get; protected internal set; }

        /// <summary>
        /// 서울시로부터 발급받은 인증키
        /// </summary>
        /// <remarks>인증키 발급: http://mobile.openapi.seoul.go.kr/ </remarks>
        public string AuthKey { get; protected internal set; }

        /// <summary>
        /// 서울시 REST형식 API 주소의 공통 부분
        /// </summary>
        public static string ApiUrlPrefix
        {
            get { return @"http://mobile.openapi.seoul.go.kr/mseoul/"; }
        }

        /// <summary>
        /// API의 정보 수신이 완료되었을 시 발생하는 이벤트
        /// </summary>
        public event DownloadDelegate OnDownloadCompleted;

        /// <summary>
        /// REST 서비스 정보 클래스
        /// </summary>
        public class REST_Data
        {
            /// <summary>
            /// 고유한 이름
            /// </summary>
            public string Name { get; set; }

            /// <summary>
            /// REST 호출 주소
            /// </summary>
            public string Address { get; set; }

            /// <summary>
            /// 설명
            /// </summary>
            public string Description { get; set; }
        }

        /// <summary>
        /// 서비스 정보를 받아옴
        /// </summary>
        /// <param name="serviceName">서비스명</param>
        /// <param name="args">입력값 (여러개) <code>new[] {args1, args2} 식으로 사용 가능함</code></param>
        /// <exception cref="KeyNotFoundException">서비스 이름이 목록에서 없을 경우</exception>
        /// <exception cref="ArgumentNullException">USER_ID 또는 AUTH_KEY가 null일 경우</exception>
        public void Request(string serviceName, object[] args)
        {
            //Validation
            if (String.IsNullOrEmpty(UserID))
                throw new ArgumentNullException(UserID);
            if (String.IsNullOrEmpty(AuthKey))
                throw new ArgumentNullException(AuthKey);

            //통신 오브젝트
            var rest = getREST_Data(serviceName);
            var webClient = new WebClient();

            //다운로드 완료되면 이벤트 리턴
            webClient.OpenReadCompleted += (s,e) => OnDownloadCompleted(e.Error == null, e.Result);
            
            //비동기 실행
            webClient.OpenReadAsync(new Uri(rest.Address,UriKind.Absolute));
        }


        /// <summary>
        /// 서비스 항목에 따라 데이터 가져오기
        /// </summary>
        /// <param name="name">서비스명</param>
        /// <returns></returns>
        protected internal virtual REST_Data getREST_Data(string serviceName)
        {
            throw new NotImplementedException("Inheritance has to be implemented this method.");
        }

        #endregion

        #region Backing Fields
        public delegate void DownloadDelegate(bool isSuccess, Stream result);
        #endregion Backing Fields
    }
}
